package com.pay.cloud.fragment;

import android.util.Log;

import com.pay.cloud.DataFactory;
import com.pay.cloud.DataStore;
import com.pay.cloud.PayApiCloud;
import com.pay.cloud.cpay.MyCloudPay;
import com.tencent.cloudpay.exception.CPayAuthenCodeCheckFail;
import com.tencent.cloudpay.exception.CPayInternalError;
import com.tencent.cloudpay.exception.CPayNetworkError;
import com.tencent.cloudpay.exception.CPayNetworkTimeout;
import com.tencent.cloudpay.exception.CPayResponseInvalid;
import com.tencent.cloudpay.param.MicroPayRequest;
import com.tencent.cloudpay.param.MicroPayResponse;
import com.tencent.cloudpay.param.QueryOrderRequest;
import com.tencent.cloudpay.param.QueryOrderResponse;
import com.tencent.cloudpay.pojo.Order;
import com.tencent.cloudpay.pojo.State;
import com.tencent.cloudpay.utils.CommonUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class PayIngFragment extends PayIngAbstract {
    private static final String TAG = PayIngFragment.class.getSimpleName();
    private String orderNo;
    private String channelOrderNo;
    public PayIngFragment(PayFinishListener listener, String barcode, String amount) {
        super(listener, barcode, amount);
    }

    public String getOrderNo() {
        return orderNo;
    }

    @Override
    public void execute() throws Exception {
        super.execute();

        String amount = new BigDecimal(this.amount).multiply(new BigDecimal("100")).setScale(0, RoundingMode.DOWN).toPlainString();
        orderNo = PayApiCloud.generateOrderNo();

        DataStore store = DataFactory.getDataStore();

        if (!barcode.matches("[0-9]{10,30}")) {
            showToast("不支持该付款码");
            showPayFail();
            return;
        }

        MicroPayRequest req = new MicroPayRequest();
        req.setAuthorCode(barcode);
        req.setBody(store.getOutSubMchId() + "-" + store.getShopName() + "-普通商品");
        req.setOutTradeNo(orderNo);
        if (isWeixinPay(barcode)) {
            req.setPayPlatform(1);
        } else if (isAlipayPay(barcode)) {
            req.setPayPlatform(2);
        } else {
            showToast("不支持该付款码");
            showPayFail();
            return;
        }
        req.setTotalFee(Long.parseLong(amount));
        Order order = null;
        try {
            MicroPayResponse res = MyCloudPay.getInstance(getActivity()).microPay(req);
            order = res.getOrder();
            channelOrderNo = order.getTransaction_id();
        } catch (Exception e) {
            if (e instanceof InterruptedException) {
                throw e;
            }
            showToast("网络异常：" + e.getMessage());
            /*
            if (!isPayResultUnknown(e)) {
                Log.e(TAG, e.getMessage(), e);
                showPayError();
                return;
            }
            */
        }

        if (null == order || isUserPaying(order.getState())) {
            queryPayStatus();
        } else if (isPayFailed(order.getState())) {
            showPayFail();
        } else {
            showPaySuccess(orderNo, channelOrderNo);
        }

    }

    private void queryPayStatus() throws Exception {
        long startTime = CommonUtils.getNowTimestamp();
        int sleepTime = 4000;
        while(true) {
            Thread.sleep(sleepTime);
            long nowTime = CommonUtils.getNowTimestamp();
            long diff = nowTime - startTime;
            if (diff >= 120) {
                showPayExpired();
                break;
            } else if (diff >= 60) {
                sleepTime = 6000;
            } else if (diff >= 30) {
                sleepTime = 5000;
            }

            try {
                QueryOrderRequest req = new QueryOrderRequest();
                req.setOut_trade_no(orderNo);
                QueryOrderResponse res = MyCloudPay.getInstance(getActivity()).queryOrder(req);
                Order order = res.getOrder();
                int state = order.getState();
                if (state == State.kCloudPaySdkLocalStateSuccess) {
                    showPaySuccess(orderNo, channelOrderNo);
                    break;
                } else if (isPayFailed(state)) {
                    showPayFail();
                    break;
                }
            } catch (Exception e) {
                if (e instanceof InterruptedException) {
                    throw e;
                }
                if (isPayResultUnknown(e)) {
                    showToast("网络异常：" + e.getMessage());
                    continue;
                }
                Log.e(TAG, e.getMessage(), e);
                showToast("查询失败：" + e.getMessage());
                //showPayError();
                //return;
            }
        }
    }

    private boolean isWeixinPay(String barcode) {
        if (barcode.length() != 18) {
            return false;
        }
        int pre = Integer.parseInt(barcode.substring(0, 2));
        return pre >= 10 && pre <=15;
    }

    private boolean isAlipayPay(String barcode) {
        int length = barcode.length();
        if (length >= 16 && length <=24) {
            int pre = Integer.parseInt(barcode.substring(0, 2));
            return pre >= 25 && pre <=30;
        }
        return false;
    }

    private boolean isPayResultUnknown(Exception e) {
        return e instanceof CPayNetworkTimeout
                || e instanceof CPayNetworkError
                || e instanceof CPayAuthenCodeCheckFail
                || e instanceof CPayResponseInvalid;
    }

    private boolean isUserPaying(int state) {
        return state == State.kCloudPaySdkLocalStateUserPaying || state == State.kCloudPaySdkLocalStateInit;
    }

    private boolean isPayFailed(int state) {
        return state == State.kCloudPaySdkLocalStateFail || state == State.kCloudPaySdkLocalStateClosed;
    }

}
